---
sidebar_position: 8
---

# Шаг 6. Переход на экспортер на конечную точку OTLP

Для визуализации и анализа вашей телеметрии нам необходимо экспортировать данные в [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) или серверную часть, такую как [Jaeger](https://www.jaegertracing.io/) или [Prometheus](https://prometheus.io/).

В рамках OpenTelemetry Python имеется множество доступных экспортеров. Среди них экспортеры протокола OpenTelemetry (OTLP) обеспечивают наилучший опыт для вас как конечного пользователя, поскольку это протокол доставки телеметрических данных общего назначения, разработанный в рамках проекта OpenTelemetry. Чтобы узнать больше о протоколе OTLP, вы можете прочитать [спецификацию OTLP](https://opentelemetry.io/docs/specs/otlp/).

Для Jaeger мы использовали специальный экспортер Jaeger [opentelemetry-exporter-jaeger](https://opentelemetry-python.readthedocs.io/en/latest/exporter/jaeger/jaeger.html). Однако Jaeger в настоящий момент поддерживает OTLP. Давайте перейдем на OLTP, опираясь на [официальную документацию](https://opentelemetry.io/docs/instrumentation/python/exporters/#otlp-endpoint-or-collector).

Чтобы отправлять данные на конечную точку OTLP или на сборщик OpenTelemetry, вам потребуется [настроить экспортер OTLP](https://opentelemetry.io/docs/instrumentation/python/exporters/#otlp-endpoint-or-collector), который отправляет данные на вашу конечную точку (Jaeger).

Сначала установите экспортер OTLP:

```python
pip install opentelemetry-exporter-otlp-proto-grpc
```

Не забудьте изменить файл `app/requirements.txt`:

```text
Flask==3.0.0
opentelemetry-sdk==1.21.0
opentelemetry-exporter-otlp-proto-grpc==1.21.0
```

Измените `app/app.py` с учетом адаптации под использование OTLP:

```python
import os
from flask import Flask
from random import randint
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
# highlight-next-line
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource

# highlight-start
resource = Resource.create({SERVICE_NAME: os.environ.get(
    'APP_SERVICE_NAME', "my-python-service")})

tracer_provider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(OTLPSpanExporter(
    endpoint=os.environ.get('TRACE_ENDPOINT', "http://localhost:4317")))
tracer_provider.add_span_processor(processor)
trace.set_tracer_provider(tracer_provider)
tracer = trace.get_tracer(__name__)
# highlight-end

app = Flask(__name__)


def roll():
    return randint(1, 6)


@app.route("/rolldice")
def roll_dice():
    with tracer.start_as_current_span("server_request"):
        return str(roll())


if __name__ == "__main__":
    host = os.environ.get('APP_HOST_NAME', "0.0.0.0")
    port = int(os.environ.get('APP_PORT', 5000))
    app.run(debug=True, host=host, port=port)

```

Также нам необходимо в `docker-compose.yaml` указать переменную окружения `TRACE_ENDPOINT`:

```docker
services:
  app:
    image: iu5devops/app
    build:
      context: ./app
      dockerfile: Dockerfile
    container_name: iu5devops-app
    networks:
      - iu5devops
    ports:
      - 8080:5000
    environment:
      - APP_SERVICE_NAME=iu5devops-app
      # highlight-start
      - TRACE_ENDPOINT=http://iu5devops-jaeger:4317
      # highlight-end

  jaeger:
    image: jaegertracing/all-in-one
    container_name: iu5devops-jaeger
    networks:
      - iu5devops
    ports:
      - 16686:16686

networks:
  iu5devops: {}

```

Соберите контейнер снова и запустите полученную конфигурацию:

```bash
docker compose down
docker compose build
docker compose up -d
```

Убедитесь, что Jaeger всё еще продолжает собирать трассировку.
